﻿@using Microsoft.CST.AttackSurfaceAnalyzer.Types
@using Microsoft.CST.AttackSurfaceAnalyzer.Objects
@inject Microsoft.CST.AttackSurfaceAnalyzer.Cli.AppData appData

<div class="form-inline pb-3">
    <label class="mr-2" for="ResultType">Result Type:</label>
    <select class="form-control mr-2" id="ResultType" @bind="SelectedResultType">
        @foreach (var resultType in foundResultTypes)
        {
            <option value="@resultType.Key">@resultType.Key : @resultType.Value </option>
        }
    </select>

    <label class="mr-2" for="MaxResults">View:</label>
    <select class="form-control" id="MaxResults" @bind="MaxResults">
        <option value="50">50</option>
        <option selected value="100">100</option>
        <option value="250">250</option>
        <option value="500">500</option>
    </select>
</div>

@if (pageCount > 0)
{
    <p>@foundResultTypes[(RESULT_TYPE)Enum.Parse(typeof(RESULT_TYPE), SelectedResultType)] results found for type @SelectedResultType.</p>
    <nav aria-label="Paged results navigation">
        <ul class="pagination">
            <li class="page-item">
                <a class="page-link page-step" aria-label="Previous page" @onclick="() => GetResultsPageByOffset(-1)">
                    <span aria-hidden="true">&lt;</span>
                    <span class="sr-only">Previous</span>
                </a>
            </li>
            @for (int i = 1; i <= pageCount; i++)
            {
                var pageNum = i;
                <li class="page-item @GetPageState(i)"><a class="page-link" aria-label="Page-@pageNum" @onclick="() => GetResultsPage(pageNum)">@pageNum</a></li>
            }
            <li class="page-item">
                <a class="page-link page-step" aria-label="Next page" @onclick="() => GetResultsPageByOffset(1)">
                    <span aria-hidden="true">&gt;</span>
                    <span class="sr-only">Next</span>
                </a>
            </li>
        </ul>
    </nav>

    @for (int i = 0; i < analysisResults.Count; i++)
    {
        var result = analysisResults[i];
        var resultNumber = offset + i + 1;
        <div class="pb-3">
            <div>
                <span class="result-number">@resultNumber. </span>
                <span class="result-text">@result.Analysis: @result.Identity</span>
            </div>
            @foreach (var rule in result.Rules)
            {
                <div class="rule-text">@rule.Name: @rule.Description</div>
            }
        </div>
    }
}
else 
{ 
    <p>0 results found for type @SelectedResultType.</p>
}

@code {
    string _firstRunId = string.Empty;
    string _secondRundId = string.Empty;
    string _analysesHash = string.Empty;
    string _monitorRunId = string.Empty;

    [Parameter]
    public string FirstRunId { get { return _firstRunId; } set { _firstRunId = value; OnInitialized(); } }
    [Parameter]
    public string SecondRunId { get { return _secondRundId; } set { _secondRundId = value; OnInitialized(); } }
    [Parameter]
    public string AnalysesHash { get { return _analysesHash; } set { _analysesHash = value; OnInitialized(); } }
    [Parameter]
    public string MonitorRunId { get { return _monitorRunId; } set { _monitorRunId = value; OnInitialized(); } }

    protected override void OnInitialized()
    {
        ParseOptsToResultTypes();
        UpdatePageCount();
        GetResultsPage(1);
        base.OnInitialized();
    }

    Dictionary<RESULT_TYPE, int> foundResultTypes = new Dictionary<RESULT_TYPE, int>();
    public List<CompareResult> analysisResults = new List<CompareResult>();
    int offset = 0;
    int currentPage = 1;
    int pageCount = 0;

    int _maxResults = 100;
    int MaxResults
    {
        get { return _maxResults; }
        set
        {
            _maxResults = value;
            UpdatePageCount();
            GetResultsPage(1);
        }
    }

    string _selectedResultType = "FILEMONITOR";
    string SelectedResultType
    {
        get { return _selectedResultType; }
        set
        {
            _selectedResultType = value;
            UpdatePageCount();
            GetResultsPage(1);
        }
    }

    void GetResultsPage(int selectedPage)
    {
        if (pageCount < 1) { return; }
        currentPage = selectedPage;
        offset = MaxResults * (selectedPage - 1);
        GetAnalysisResults();
        this.StateHasChanged();
    }

    void GetResultsPageByOffset(int pageOffset)
    {
        var selectedPage = currentPage + pageOffset;
        if (selectedPage < 1) { selectedPage = 1;}
        else if (selectedPage > pageCount) { selectedPage = pageCount; }
        GetResultsPage(selectedPage);
    }

    string GetPageState(int selectedPage)
    {
        return selectedPage == currentPage ? "active" : "";
    }

    public void UpdatePageCount()
    {
        var resultType = (RESULT_TYPE)Enum.Parse(typeof(RESULT_TYPE), SelectedResultType);
        var found = foundResultTypes[resultType];      
        pageCount = (int)Math.Ceiling((double)found / MaxResults);
        currentPage = 1;
    }

    public void GetAnalysisResults()
    {
        if (AttackSurfaceAnalyzerClient.DatabaseManager is null)
        {
            analysisResults = new List<CompareResult>();
            return;
        }
        var resultType = (RESULT_TYPE)Enum.Parse(typeof(RESULT_TYPE), SelectedResultType);
        switch (resultType)
        {
            case RESULT_TYPE.FILEMONITOR:
                analysisResults = AttackSurfaceAnalyzerClient.DatabaseManager.GetComparisonResults(string.Empty, MonitorRunId, AnalysesHash, resultType, offset, MaxResults);
                break;
            default:
                analysisResults = AttackSurfaceAnalyzerClient.DatabaseManager.GetComparisonResults(FirstRunId, SecondRunId, AnalysesHash, resultType, offset, MaxResults);
                break;
        }
    }

    public void ParseOptsToResultTypes()
    {
        foundResultTypes.Clear();
        if (AttackSurfaceAnalyzerClient.DatabaseManager is null)
        {
            return;
        }        
        foreach (var resultType in Enum.GetValues(typeof(RESULT_TYPE)))
        {
            var found = AttackSurfaceAnalyzerClient.DatabaseManager.GetComparisonResultsCount(FirstRunId, SecondRunId, AnalysesHash, (int)resultType);
            if (found == 0)
            {
                found = AttackSurfaceAnalyzerClient.DatabaseManager.GetComparisonResultsCount(string.Empty, MonitorRunId, AnalysesHash, (int)resultType);
            }
            foundResultTypes.Add((RESULT_TYPE)resultType, found);
        }
    }
}
